/**
 * Name         Cell Zooming in Green Cellular Networks
 * @File        Grid.cpp
 * Authors      Bruno Saldanha Carminati & Marcelo Faleiros Costa
 * Date         May 2012
 *
 * This file is part of the undergraduate final project, 
 * under the supervision of André Noll Barreto
 */

#include <cstdlib>
#include <iostream>
#include <math.h>
#include <vector>
#include "BaseStation.h"
#include "Grid.h"
#include "random.h"

using namespace std;

/**
 * Class constructor
 */
Grid::Grid(int colsNum, int rowsNum) {
    this->colsNum = colsNum;
    this->rowsNum = rowsNum;
}

/**
 * Generates hexagonal grid
 * Returns vector of BaseStation containing all base stations' coordinates
 */
void Grid::generate(std::vector<BaseStation>& baseStationVector, double averageCellRadius, double cellRadiusPercentDeviation) {
    int rowsGridCounter = 0, colsGridCounter = 0;
    int rowsMatrixCounter = 0, colsMatrixCounter = 0, quadrantMatrixCounter = 0, Counter = 0;
    random* r;
    r = new random();
    BaseStation* baseStation;
    
    for (rowsGridCounter = 0; rowsGridCounter < this->rowsNum; rowsGridCounter++) {
        for (colsGridCounter = 0; colsGridCounter < this->colsNum; colsGridCounter++) {
            /* Calculates random number with uniform distribution between maximum and minimum deviation from average */
            double cellRadiusDeviation = cellRadiusPercentDeviation*averageCellRadius/100;
            double randomRadius = r->uniform(averageCellRadius-cellRadiusDeviation,averageCellRadius+cellRadiusDeviation);
            
            /* Sets base station site */
            baseStation = new BaseStation(randomRadius*0.5*(4*colsGridCounter+1-pow(-1,rowsGridCounter)),sqrt(3)*randomRadius*rowsGridCounter,r->uniform(30,40));
            
            /* Fills shadowing factor matrix with random values */
            for (quadrantMatrixCounter = 0; quadrantMatrixCounter < 3; quadrantMatrixCounter++) {
                for (rowsMatrixCounter = 0; rowsMatrixCounter < 50; rowsMatrixCounter++) {
                    for (colsMatrixCounter = 0; colsMatrixCounter < 50; colsMatrixCounter++) {
                        /* The shadowing factor in urban macrocells has normal distribution with mean = 0 and standard deviation = 8 dB */
                        baseStation->shadowingFactorMatrix[quadrantMatrixCounter][rowsMatrixCounter][colsMatrixCounter] = r->normal(0,8);
                    }
                }
            }
            
            /* Copies shadowing factor for columns and rows between quadrants to avoid discontinuities */
            for (Counter = 0; Counter < 50; Counter++) {
                baseStation->shadowingFactorMatrix[1][Counter][49] = baseStation->shadowingFactorMatrix[0][Counter][0];
                baseStation->shadowingFactorMatrix[2][0][Counter] = baseStation->shadowingFactorMatrix[1][49][Counter];
                baseStation->shadowingFactorMatrix[3][Counter][0] = baseStation->shadowingFactorMatrix[3][Counter][49];
                baseStation->shadowingFactorMatrix[3][0][Counter] = baseStation->shadowingFactorMatrix[0][49][Counter];
            }
            
            /* Pushes base station recently created back into vector */
            baseStationVector.push_back(*baseStation);
//            cout << "BTS " << rowsGridCounter*this->colsNum+colsGridCounter << "\t" << baseStation->xPos << "\t" << baseStation->yPos << "\t" << baseStation->zPos << endl;
//            cout << "BTS " << rowsGridCounter*this->colsNum+colsGridCounter << "\t" << baseStation->shadowingFactorMatrix[0][0] << endl;
            delete baseStation;
        }
    }
    delete r;
}
